package com.lyfx.ly.service.impl;

import com.lyfx.common.constant.CourseStatusEnum;
import com.lyfx.common.to.es.AttrModel;
import com.lyfx.common.to.es.CourseModel;
import com.lyfx.common.utils.MyArrayUtils;
import com.lyfx.common.utils.R;
import com.lyfx.ly.entity.*;
import com.lyfx.ly.feign.SearchFeignService;
import com.lyfx.ly.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyfx.common.utils.PageUtils;
import com.lyfx.common.utils.Query;

import com.lyfx.ly.dao.ClassCourseEstypeDao;
import org.springframework.transaction.annotation.Transactional;


@Service("classCourseEstypeService")
public class ClassCourseEstypeServiceImpl extends ServiceImpl<ClassCourseEstypeDao, ClassCourseEstypeEntity> implements ClassCourseEstypeService {

    @Autowired
    ClassCourseService classCourseService;

    @Autowired
    ClassCourseCategoryService classCourseCategoryService;

    @Autowired
    ClassCategoryService classCategoryService;

    @Autowired
    AttrService attrService;

    @Autowired
    ClassCourseAttrValuesService attrValuesService;

    @Autowired
    SearchFeignService searchFeignService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ClassCourseEstypeEntity> page = this.page(
                new Query<ClassCourseEstypeEntity>().getPage(params),
                new QueryWrapper<ClassCourseEstypeEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void up(Long courseId) {
        //1、组装数据
        CourseModel courseModel = new CourseModel();
        //查出courseid对应的信息
        ClassCourseEntity byId = classCourseService.getById(courseId);
        BeanUtils.copyProperties(byId, courseModel);
        //classImg  categoryId categoryName attrs
        courseModel.setClassImg(byId.getLogo());
        ClassCourseCategoryEntity one = classCourseCategoryService.getOne(new QueryWrapper<ClassCourseCategoryEntity>().eq("course_id", courseId));
        courseModel.setCategoryId(one.getCategoryId());
        courseModel.setCategoryName(one.getCategoryName());
        //查询此课程的属性,可以被检索的属性
        List<ClassCourseAttrValuesEntity> baseAttrs = attrValuesService.baseAttrForCourse(courseId);

        List<Long> attrIds = baseAttrs.stream().map(ClassCourseAttrValuesEntity::getAttrId).collect(Collectors.toList());
        List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
        Set<Long> idSet = new HashSet<>(searchAttrIds);

        List<CourseModel.Attrs> attrs = new ArrayList<>();
        List<AttrModel> attrmodel = baseAttrs.stream().filter(item -> {
            return idSet.contains(item.getAttrId());
        }).map(obj -> {
            AttrModel attrModel = new AttrModel();
            BeanUtils.copyProperties(obj, attrModel);
            return attrModel;
        }).collect(Collectors.toList());
        List<List<AttrModel>> lists = attrsDescartes(attrmodel);
        List<CourseModel> courseModels = lists.stream().map(item -> {
            CourseModel newCourseModel = new CourseModel();
            BeanUtils.copyProperties(courseModel, newCourseModel);
            List<CourseModel.Attrs> collect = item.stream().map(obj -> {
                CourseModel.Attrs cou = new CourseModel.Attrs();
                BeanUtils.copyProperties(obj, cou);
                return cou;
            }).collect(Collectors.toList());
            newCourseModel.setAttrs(collect);
            return newCourseModel;
        }).collect(Collectors.toList());

        //将数据发送给es服务进行保存
        R r = searchFeignService.courseStatusUp(courseModels);
        if(r.get("code").toString().equals("0")){
            //远程调用成功
            //更改状态
            this.baseMapper.updateCourseStatus(courseId, CourseStatusEnum.UP_COURSE.getCode());
        }else{
            //失败
            //TODO 重复调用，接口幂等性,重试机制
        }
    }

    /**
     * 生成笛卡尔积
     * @param attrmodel
     */
    private List<List<AttrModel>> attrsDescartes(List<AttrModel> attrmodel) {
        List<AttrModel> newlist = new ArrayList<>();
        for (int i=0;i<attrmodel.size();i++) {
            if(attrmodel.get(i).getAttrValue().contains(";")){
                String[] split = attrmodel.get(i).getAttrValue().split(";");
                for (String s : split) {
                    AttrModel model = new AttrModel();
                    BeanUtils.copyProperties(attrmodel.get(i), model);
                    model.setAttrValue(s);
                    model.setType((i+1));
                    newlist.add(model);
                }
            }else{
                attrmodel.get(i).setType((i+1));
                newlist.add(attrmodel.get(i));
            }
        }
        // 按指定字段（type）分组
        Map<Integer, List<AttrModel>> modelMap = newlist.stream().collect(Collectors.groupingBy(AttrModel::getType));
        Collection<List<AttrModel>> mapValues = modelMap.values();
        List<List<AttrModel>> dimensionValue = new ArrayList<>(mapValues);	// 原List

        List<List<AttrModel>> result = new ArrayList<>(); // 返回集合
        new MyArrayUtils().descartes(dimensionValue, result, 0, new ArrayList<AttrModel>());
        return result;
    }

}